/*******************************************************************************
 * This file is part of blueprint4j www.blueprint4j.org.
 * 
 *     blueprint4j is free software: you can redistribute it and/or modify
 *     it under the terms of the GNU Lesser General Public License as published by
 *     the Free Software Foundation, either version 3 of the License, or
 *     (at your option) any later version.
 * 
 *     blueprint4j is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *     GNU Lesser General Public License for more details.
 * 
 *     You should have received a copy of the GNU Lesser General Public License
 *     along with blueprint4j. If not, see <http://www.gnu.org/licenses/>.
 ******************************************************************************/
/**
* $Log: MessageDelimited.java,v $
* Revision 1.1.1.1  2004/04/22 12:56:14  travisb
* Fir
*
* Revision 1.1.1.1  2003/12/21 09:04:08  jaspervdb
* no message
*
* Revision 1.2  2003/11/03 07:24:30  jasper
* no message
*
* Revision 1.1.1.1  2003/10/20 15:30:48  travisb
* First import into CVS at Cellstop
*
* Revision 1.1.1.1  2003/03/30 15:25:28  tbulford
* no message
*
* Revision 1.1  2003/01/12 08:30:34  travis
* Import x MANY
*
* Revision 1.1.1.1  2002/12/16 22:14:01  jasper
* no message
*
**
*/
package blueprint4j.messages;

import java.io.*;
import java.util.*;

import blueprint4j.utils.*;

public class MessageDelimited extends Message {
	private String delimiter;
	private String name = "Unnamed";
	Vector fields = new Vector();
	int max_fields=100;
	private final int MAX_FIELD_SIZE=1000;
	private byte[] datad;
	private byte[] datain=new byte[MAX_FIELD_SIZE];

	public MessageDelimited( String p_delimiter ) {
		delimiter = p_delimiter;
		datad=delimiter.getBytes();
	}

	public void setMaxFields(int p_max_fields){
		max_fields=p_max_fields;
	}

	/**
	* Sets all the message details from a properties file
	* @param props
	*/
	public void setMessage( Properties props )
	throws ExceptionMessage {}


	/**
	* Returns all the message details in properties file
	* the properties are formatted as follows <br>
	*/
	public Properties getMessage()
	throws ExceptionMessage {
		return null;
	}


	/**
	* Returns all the message details in properties string
	*/
	public String getMessageAsString()
	throws ExceptionMessage {
		String str = "";
		for (int i = 0;i < fields.size();i++) {
			//if (i < fields.size()-1) {
			//	str += fields.get(i) + delimiter;
			//} else {
				str += fields.get(i) + delimiter;
			//}
		}
		return str;
	}


	/**
	* Overloaded to return a more suitable name
	*/
	public String toString() {
		return "Delimited message with '" + delimiter + "' called " + name;
	}


	/**
	* Set this message name
	* @param
	*/
	public void setName( String p_name ) {
		name = p_name;
	}


	/**
	* Get this message name
	*/
	public String getName() {
		return name;
	}

	/**
	* Sets the message type
	*/
	public void setType( String p_message_type )
	throws ExceptionMessage {
		set( 0, p_message_type );
	}

	/**
	* Returns the message type
	*/
	public String getType()
	throws ExceptionMessage {
		return get( 0 );
	}

	/**
	* Check is a field is defined
	* @param
	*/
	public boolean hasField( int field )
	throws ExceptionMessage {
		return field < fields.size();
	}


	/**
	* Check is a field is defined
	* @param
	*/
	public boolean hasField( String field )
	throws ExceptionMessage {
		try {
			return hasField( Integer.parseInt( field ) );
		} catch ( NumberFormatException nfe ) {}
		return false;
	}


	/**
	* Get the max width for the field
	* @param
	*/
	public int getMaxFieldWidth( int field )
	throws ExceptionMessage {
		return 0x7ffffff;
	}


	/**
	* Get the max width for the field
	* @param
	*/
	public int getMaxFieldWidth( String field )
	throws ExceptionMessage {
		return 0x7ffffff;
	}


	public String get( int field_no )
	throws ExceptionMessage {
		if ( hasField( field_no ) ) {
			return ( String ) fields.get( field_no );
		} else {
			throw new ExceptionMessage( "Field [" + field_no + "] asked for, but only [" + fields.size() + "] fields available" );
		}
	}

	public String get( String field )
	throws ExceptionMessage {
		try {
			return get( Integer.parseInt( field ) );
		} catch ( NumberFormatException nfe ) {
			throw new ExceptionMessage( "Field [" + field + "] asked for, but only not found" );
		}
	}


	public void set( int field_no, String p_value )
	throws ExceptionMessage {
		try {
			// Add number of elements
			while ( fields.size() <= field_no ) {
				fields.add( null );
			}
			// Set desired element
			fields.setElementAt( p_value, field_no );
		} catch ( NumberFormatException nfe ) {
			throw new ExceptionMessage( "Field [" + field_no + "] asked for, but only not found" );
		}
	}

	public void set( String field, String p_value )
	throws ExceptionMessage {
		try {
			set( Integer.parseInt( field ), p_value );
		} catch ( NumberFormatException nfe ) {
			throw new ExceptionMessage( "Field [" + field + "] being set, but only not found" );
		}
	}

	public void setBinary( int field_no, byte[] p_value )
	throws ExceptionMessage {
		set( field_no, new String( p_value ) );
	}


	public void setBinary( String field, byte[] p_value )
	throws ExceptionMessage {
		set( field, new String( p_value ) );
	}

	public void read( InputStream input )
	throws ExceptionMessage, IOException {
		fields.removeAllElements();
		byte buffer [] = new byte [1024];
		String str_buffer = "";
		while (input.available() > 0) {
			int r = input.read(buffer);
			if (r != -1) {
				str_buffer += new String(buffer,0,r);
			}
		}
      VectorString vs = new VectorString(str_buffer,delimiter);
      for (int i = 0;i < vs.size();i++)
         set(i,vs.get(i));
		//StringTokenizer tokenizer = new StringTokenizer(str_buffer,delimiter);
		//for (int i = 0;i < tokenizer.countTokens();i++) {
		//	set(i,tokenizer.nextToken());
		//}
		/*
		if ( input.available() > 0 ) {
			int bytes=input.available();
			int delimiter_size=delimiter.length();
			int field_number=0;
			if (input.read(datain,0,bytes)!=bytes){
				throw new IOException("Wrong number of bytes returned from stream.");
			}
			boolean end;
			int dc;
			int laststart=0;
			for (int t=0;t<bytes;t++){
				// Check for end
				end=(t==bytes-1);
				dc=0;
				for (int e=0;e<delimiter_size && !end;e++){
					if (datain[t+e]==datad[e]) dc++;
				}
				if (dc==delimiter_size){
					end=true;
				}
				if (end){
					// Next row
					set( field_number++, new String(datain,laststart,t-laststart));
					t+=delimiter_size-1;
					laststart=t+1;
				}
			}
		}
		StreamProtocolInputBreakString instream = new StreamProtocolInputBreakString( delimiter );
		instream.setStream( input );
		// Read from stream
		fields.removeAllElements();
		for ( int field = 0; field<max_fields ; field++ ) {
			if ( instream.available() > 0 ) {
				byte[] b = new byte[ instream.available() ];
				instream.read( b );
				setBinary( field, b );
			}
			instream.close();
		}*/
		//throw new ExceptionMessage("This method Has not been implemented");
	}

	public void write( OutputStream output )
	throws ExceptionMessage, IOException {
		/*
		StreamProtocolOutputBreakString outstream = new StreamProtocolOutputBreakString( delimiter );
		outstream.setStream( output );
		for ( int field = 0;field < fields.size();field++ ) {
			String item = get( field );
			if ( item == null ) {
				item = "";
			}
			outstream.write( item.getBytes() );
			outstream.flush();
		}*/
		for ( int field = 0;field < fields.size();field++ ) {
			String item = get( field );
			if ( item == null ) {
				item = "";
			}
			output.write(item.getBytes());
			output.write(delimiter.getBytes());
		}
	}

}

